package kandl.automation.utils;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Map;

public class FileResourceClientRequestHttpFactory implements ClientHttpRequestFactory {

    private final Map<URI, Resource> resourceMap;
    private final MediaType mediaType;

    public FileResourceClientRequestHttpFactory(Map<URI, Resource> resourceMap, MediaType mediaType) {
        this.resourceMap = resourceMap;
        this.mediaType = mediaType;
    }

    public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
        return new FileClientHttpRequest(resourceMap.get(uri), httpMethod);
    }

    private class FileClientHttpRequest implements ClientHttpRequest {

        private final Resource resource;
        private final HttpMethod httpMethod;

        public FileClientHttpRequest(Resource resource, HttpMethod httpMethod) {
            this.resource = resource;
            this.httpMethod = httpMethod;
        }

        public HttpMethod getMethod() {
            return httpMethod;
        }

        public URI getURI() {
            return null;
        }

        public HttpHeaders getHeaders() {
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.add("Accept", MediaType.toString(Arrays.asList(mediaType)));

            return httpHeaders;
        }

        public OutputStream getBody() throws IOException {
            return new NullOutputStream();
        }

        @Override
        public ClientHttpResponse execute() throws IOException {
            return new ClientHttpResponse() {
                private InputStream inputStream;

                public HttpHeaders getHeaders() {
                    HttpHeaders httpHeaders = new HttpHeaders();
                    httpHeaders.setContentType(mediaType);

                    return httpHeaders;
                }

                public InputStream getBody() throws IOException {
                    inputStream = resource.getInputStream();

                    return inputStream;
                }

                public String getStatusText() throws IOException {
                    return "";
                }

                public HttpStatus getStatusCode() throws IOException {
                    return HttpStatus.OK;
                }

                public int getRawStatusCode() throws IOException {
                    return getStatusCode().value();
                }

                public void close() {
                    IOUtils.closeQuietly(inputStream);
                }
            };
        }
    }
}
